package com.szxx.domain;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.szxx.constans.PokerGameConstant;

/**
 * 牌 <br>
 *
 * @author Ambrose
 */
public class Card implements Cloneable, Comparable<Card> {
	
	private static Logger logger = LoggerFactory.getLogger(Card.class);
	
	/** 花色 */
	private CardShape cardShape;
	/** 点数 */
	private int number;
	/**
	 * 牌实际值 <br>
	 * 权重设计，在斗地主游戏中，3<A<2，在比牌类游戏中，单牌型红桃K<黑桃K，cardShape+value还可以用来排序
	 */
	private int value;
	
	public Card(CardShape cardShape, int number) {
		this.cardShape = cardShape;
		this.number = number;
	}
	
	public Card(CardShape cardShape, int number, int value) {
		this.cardShape = cardShape;
		this.number = number;
		this.value = value;
	}
	
	/**
	 * 初始化 <br>
	 * 一般用于填充value值
 * 
	 * @return 返回this指针用于编程方便
	 */
	public Card revalue() {
		if (cardShape == CardShape.RED_JOKER) { // 大王
			number = PokerGameConstant.RED_JOKER_SHAPE_NUM;
			value = PokerGameConstant.RED_JOKER_SHAPE_VALUE;
		} else if (cardShape == CardShape.BLACK_JOKER) { // 小王
			number = PokerGameConstant.BLACK_JOKER_SHAPE_NUM;
			value = PokerGameConstant.BLACK_JOKER_SHAPE_VALUE;
		} else {
			if (number == 1 ) {
				value = PokerGameConstant.NUMBER_1_VALUE;
			} else if (number == 2) {
				value = PokerGameConstant.NUMBER_2_VALUE;
			} else {
				value = number;
			}
		}
		return this;
	}
	
	@Override
	public Card clone() {
		try {
			return (Card) super.clone();
		} catch (CloneNotSupportedException e) {
			logger.error("can not clone for card:[{}, {}, {}]", cardShape ,number , value, e);
		}
		return new Card(cardShape, number, value);
	}
	
	/**
	 * 不带花色的比较，用于点数比较 <br>
	 */
	@Override
	public int compareTo(Card o) {
		if (o == null) {
			return 1;
		} else {
			return value - o.value;
		}
	}
	
	/**
	 * 带花色的比较，用于排序 <br>
	 * 黑红梅方 value 小的在前面
	 * 
	 * @param o
	 * @return
	 */
	public int compareWithShapeTo(Card o) {
		if (o == null) {
			return 1;
		} else {
			int weight_c = value - o.value;
			if (weight_c == 0) {
				if (o.cardShape == null) {
					return 1;
				} else {
					return cardShape.getShape() - o.cardShape.getShape();
				}
			} else {
				return weight_c;	
			}
		}
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cardShape == null) ? 0 : cardShape.hashCode());
		result = prime * result + number;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Card other = (Card) obj;
		if (cardShape != other.cardShape)
			return false;
		if (number != other.number)
			return false;
		return true;
	}
	
	@Override
	public String toString() {
		return "" + cardShape.getSimpleName() + "" + number + "";
	}

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}

	public CardShape getCardShape() {
		return cardShape;
	}

	public int getNumber() {
		return number;
	}
	
}
